#include "Cell.h"

#include <boost/smart_ptr.hpp>

#include "BlackHole.h"
#include "Gangster.h"
#include "Wall.h"
#include "Bullet.h"
#include "Object.h"
#include "PriorityQueue.h"
#include "Field.h"

  // operators are inverted
bool Cell::operator < ( Cell& c ) {
    return getF() > c.getF();
}

bool Cell::operator > ( Cell& c ) {
    return getF() < c.getF();
}

bool Cell::operator == ( Cell& c ) {
    return getF() == c.getF();
}

bool Cell::operator <= ( Cell& c ) {
    return getF() >= c.getF();
}

bool Cell::operator >= ( Cell& c ) {
    return getF() <= c.getF();
}

bool Cell::isNull() {
    if( getX() < 0 || getY() < 0 || getTime() < 0 ||
        getX() > Field::HEIGHT || getX() > Field::WIDTH ) { return false; }
    return true;
}

int manhattanDistance( int x1, int y1, int x2, int y2 ) {
     return ( abs(x2 - x1) + abs(y2 - y1) );
}

bool isPassable( Object* o ) {
    if( o == 0 ) return true;
    else if(  o->getSymbol() == Bullet::BULLETCHAR ) {
        return true;
    } else return false;
    /*switch( o->getSymbol() ) {
        case( Wall::WALLCHAR ):           return false;
        case( Gangster::GANGSTERCHAR ):   return false;
        case( BlackHole::BLACKHOLECHAR ): return false;
        case( Bullet::BULLETCHAR ):       return true;
        default: return false;
    }*/
}

int movementCost( Cell c ) {
    int g = 0;
    Cell d = c;
    if( c.isNull() ) {
        while( d.getPath() != 0 && d.getPath()->isNull() ) {
            g += d.getG();
            d = *( d.getPath() );
        }
        g += Controller::BASEMOVEMENTCOST;
    }
    if( c.getPath() == 0 ) g -= 1;
    return g;
}

bool isInList( int x, int y, vector<Cell>& list ) {
     int size = list.size();
     for( int i = 0; i < size; i++ ) {
         if( list[i].getX() == x && list[i].getY() == y ) {
            return true;
         }
     }
     return false;
}

Cell getFromList( int x, int y, vector<Cell>& list ) {
    int size = list.size();
    for( int i = 0; i < size; i++ ) {
        if( list[i].getX() == x && list[i].getY() == y ) {
           return list[i];
        }
    }
    return Cell( -1, -1, 0, 0, 0 );
}

int calcF( int x2, int y2, Cell c ) {
    return manhattanDistance( c.getX(), c.getY(), x2, y2 )/* + movementCost( c )*/;
}

bool isNull( void* pointer ) {
    if( pointer ) return true;
    return false;
}
